/* eslint-disable no-restricted-syntax */
/* eslint-disable @typescript-eslint/no-use-before-define */
import {
  // GridItemDataInterface,
  KeyValueStore,
} from '@/components/vueGridLayout/interfate/grid-Item-data-inteface'
import {
  // viewData,
  preCalculate,
} from '@/api/recommend-visualization'
import { getWidgetData } from '@/api/widget'
import { chart2ArrayChartType, ChartDetailsEnum } from '@/config/contant'
import { IColumn } from '@/store/modules/dataview'
import { sortBy } from 'lodash'
import { getWidgetJson } from '@/config/setting-chart'
import { apiGetTableData } from '@/api/data-clean'
import { dealData } from '@/components/studio/data/util'
import { simpleCommonDefultOptions } from '@/components/common/VisualizationComp/default-chart-options' // 默认配置
// import algorithmRecommend from '@/util/algorithm-recommend'
import {
  getRecommendParametersBySemantic,
  getRecommendParametersByType,
} from '@/util/semantic-recommend'

// import { testCalculateData, testWidgetData } from '@/util/test-data'

interface DataField {
  name: string
  type: number // TODO: ordinal, datetime
  desc: string
  semantic?: string
}

interface DataSet {
  id: string
  fields: DataField[]
}

export interface VisSpec {
  dataset: DataSet
  tableName: string
  dataTransform?: {
    transformMethod: string
    transformConfig: {
      [any: string]: any
    }
  }
  chartType: ChartDetailsEnum
  chartConfig: {
    groups: IColumn[]
    keys: IColumn[]
    values: IColumn[]
  }
}

export interface RecommendParameters {
  transformSetting?: [
    {
      transformMethod: string
      transformConfig: {
        [any: string]: any
      }
    }
  ]
  chartSetting: {
    chartType: ChartDetailsEnum
    chartConfig: {
      groups: IColumn[]
      keys: IColumn[]
      values: IColumn[]
      [key: string]: any
    }
  }
}

interface BinField extends IColumn {
  binCount?: number
}

interface BinConfig {
  binFields: BinField[]
  binMethod: string
  targetField?: DataField
}

// const binMethodsMap: any = {
//   count: 'count',
//   average: 'avg',
// }

// function getUsedFields(spec: VisSpec): DataField[] {
//   const array: DataField[] = []
//   return array.concat(spec.chartConfig.keys, spec.chartConfig.values)
// }

// function recommendVisByFields(
//   spec: VisSpec,
//   usedFields: DataField[]
// ): VisSpec[] {
//   const categoricalFields = usedFields.filter(
//     (field) => field.type === 'categorical'
//   )
//   const quantitativeFields = usedFields.filter(
//     (field) => field.type === 'quantitative'
//   )
//   const categoricalCount = categoricalFields.length
//   const quantitativeCount = quantitativeFields.length

//   const result: VisSpec[] = []
//   if (categoricalCount === 0 && quantitativeCount === 0) {
//     // 平行坐标
//     const values = spec.dataset.fields.filter(
//       (field) => field.type === 'quantitative'
//     )
//     if (values.length > 1) {
//       // result.push({
//       //   dataset: spec.dataset,
//       //   tableName: spec.tableName,
//       //   chartType: ChartDetailsEnum.parallelCoordinates,
//       //   chartConfig: {
//       //     groups: [],
//       //     keys: [],
//       //     values,
//       //   },
//       // })
//     }
//   } else if (categoricalCount === 1 && quantitativeCount === 0) {
//     result.push(
//       {
//         dataset: spec.dataset,
//         tableName: spec.tableName,
//         dataTransform: {
//           transformMethod: 'bin',
//           transformConfig: <BinConfig>{
//             binFields: categoricalFields,
//             binMethod: 'count',
//           },
//         },
//         chartType: ChartDetailsEnum.barChart,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: [{ id: 'count', type: 'quantitative' }],
//         },
//       },
//       {
//         dataset: spec.dataset,
//         tableName: spec.tableName,
//         dataTransform: {
//           transformMethod: 'bin',
//           transformConfig: {
//             binFields: categoricalFields,
//             binMethod: 'count',
//           },
//         },
//         chartType: ChartDetailsEnum.pieChart,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: [{ id: 'count', type: 'quantitative' }],
//         },
//       }
//     )
//   } else if (categoricalCount === 0 && quantitativeCount === 1) {
//     const binCounts = [5, 10, 15]
//     const binMethods = ['count', 'average' /* , 'variance' */]
//     binCounts.forEach((binCount) => {
//       binMethods.forEach((binMethod) => {
//         const targetField = quantitativeFields[0]
//         const newFieldName =
//           binMethod === 'count'
//             ? binMethod
//             : `${binMethodsMap[binMethod]}_${targetField.id}`
//         result.push({
//           dataset: spec.dataset,
//           tableName: spec.tableName,
//           dataTransform: {
//             transformMethod: 'bin',
//             transformConfig: <BinConfig>{
//               binFields: [{ ...quantitativeFields[0], binCount }],
//               binMethod,
//               targetField,
//             },
//           },
//           chartType: ChartDetailsEnum.barChart,
//           chartConfig: {
//             groups: [],
//             keys: quantitativeFields.map((field) => ({
//               ...field,
//               id: `${field.id}_after`,
//             })),
//             values: [{ id: newFieldName, type: 'quantitative' }],
//           },
//         })
//       })
//     })
//   } else if (categoricalCount === 2 && quantitativeCount === 0) {
//     result.push(
//       {
//         dataset: spec.dataset,
//         tableName: spec.tableName,
//         dataTransform: {
//           transformMethod: 'bin',
//           transformConfig: <BinConfig>{
//             binFields: categoricalFields,
//             binMethod: 'count',
//           },
//         },
//         chartType: ChartDetailsEnum.stackBarChart,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: [{ id: 'count', type: 'quantitative' }],
//         },
//       },
//       {
//         dataset: spec.dataset,
//         tableName: spec.tableName,
//         dataTransform: {
//           transformMethod: 'bin',
//           transformConfig: <BinConfig>{
//             binFields: categoricalFields,
//             binMethod: 'count',
//           },
//         },
//         chartType: ChartDetailsEnum.heatmapMatrix,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: [{ id: 'count', type: 'quantitative' }],
//         },
//       }
//     )
//   } else if (categoricalCount === 0 && quantitativeCount === 2) {
//     result.push({
//       dataset: spec.dataset,
//       tableName: spec.tableName,
//       chartType: ChartDetailsEnum.scatterplot,
//       chartConfig: {
//         groups: [],
//         // rows: [], // TODO
//         // values: quantitativeFields,
//         keys: [quantitativeFields[0]],
//         values: [quantitativeFields[1]],
//       },
//     })

//     const binCounts = [5, 10, 15]
//     const binMethods = [/* 'count', */ 'average' /* , 'sum', 'variance' */]

//     // 现在的scatterplot不支持
//     // binCounts.forEach((binCount) => {
//     //   result.push({
//     //     dataset: spec.dataset,
//     //     dataTransform: {
//     //       transformMethod: 'bin',
//     //       transformConfig: <BinConfig>{
//     //         binFields: quantitativeFields.map((field) => ({
//     //           ...field,
//     //           binCount,
//     //         })),
//     //         binMethod: 'count',
//     //       },
//     //     },
//     //     chartType: ChartDetailsEnum.scatterplot,
//     //     chartConfig: {
//     //       columns: [],
//     //       rows: quantitativeFields,
//     //       values: [{ id: 'count', type: 'quantitative' }],
//     //     },
//     //   })
//     // })

//     binCounts.forEach((binCount) => {
//       binMethods.forEach((binMethod) => {
//         quantitativeFields.forEach((field, index) => {
//           const targetField = quantitativeFields[1 - index]
//           const newFieldName = `${binMethodsMap[binMethod]}_${targetField.id}`
//           result.push({
//             dataset: spec.dataset,
//             tableName: spec.tableName,
//             dataTransform: {
//               transformMethod: 'bin',
//               transformConfig: <BinConfig>{
//                 binFields: [{ ...field, binCount }],
//                 binMethod,
//                 targetField,
//               },
//             },
//             chartType: ChartDetailsEnum.barChart,
//             chartConfig: {
//               groups: [],
//               keys: [
//                 {
//                   ...field,
//                   id: `${field.id}_after`,
//                 },
//               ],
//               values: [{ id: newFieldName, type: 'quantitative' }],
//             },
//           })
//         })
//       })
//     })
//   } else if (categoricalCount === 1 && quantitativeCount === 1) {
//     result.push({
//       dataset: spec.dataset,
//       tableName: spec.tableName,
//       chartType: ChartDetailsEnum.scatterplot,
//       chartConfig: {
//         groups: [],
//         keys: categoricalFields,
//         values: quantitativeFields,
//       },
//     })

//     // const binCounts = [5, 10, 15]
//     const binMethods = [/* 'count', */ 'average' /* , 'sum', 'variance' */]

//     // 现在的scatterplot不支持
//     // binCounts.forEach((binCount) => {
//     //   result.push({
//     //     dataset: spec.dataset,
//     //     dataTransform: {
//     //       transformMethod: 'bin',
//     //       transformConfig: <BinConfig>{
//     //         binFields: [
//     //           ...categoricalFields,
//     //           { ...quantitativeFields[0], binCount },
//     //         ],
//     //         binMethod: 'count',
//     //       },
//     //     },
//     //     chartType: ChartDetailsEnum.scatterplot,
//     //     chartConfig: {
//     //       columns: [],
//     //       rows: categoricalFields.concat(quantitativeFields),
//     //       values: [{ id: 'count', type: 'quantitative' }],
//     //     },
//     //   })
//     // })

//     binMethods.forEach((binMethod) => {
//       const newFieldName = `${binMethodsMap[binMethod]}_${quantitativeFields[0].id}`
//       result.push({
//         dataset: spec.dataset,
//         tableName: spec.tableName,
//         dataTransform: {
//           transformMethod: 'bin',
//           transformConfig: <BinConfig>{
//             binFields: categoricalFields,
//             binMethod,
//             targetField: quantitativeFields[0],
//           },
//         },
//         chartType: ChartDetailsEnum.barChart,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: [{ id: newFieldName, type: 'quantitative' }],
//         },
//       })
//     })
//   }
//   // 现在的scatterplot不支持
//   //  else if (categoricalCount === 2 && quantitativeCount === 1) {
//   //   result.push({
//   //     dataset: spec.dataset,
//   //     chartType: ChartDetailsEnum.scatterplot,
//   //     chartConfig: {
//   //       columns: [],
//   //       rows: categoricalFields,
//   //       values: quantitativeFields,
//   //     },
//   //   })
//   // }
//   // 现在的scatterplot不支持
//   // else if (categoricalCount === 1 && quantitativeCount === 2) {
//   //   result.push({
//   //     dataset: spec.dataset,
//   //     chartType: ChartDetailsEnum.scatterplot,
//   //     chartConfig: {
//   //       columns: [],
//   //       rows: categoricalFields,
//   //       values: quantitativeFields,
//   //     },
//   //   })
//   // }
//   // 现在的scatterplot不支持
//   // else if (categoricalCount === 0 && quantitativeCount === 3) {
//   //   result.push({
//   //     dataset: spec.dataset,
//   //     chartType: ChartDetailsEnum.scatterplot,
//   //     chartConfig: {
//   //       columns: [],
//   //       rows: [],
//   //       values: quantitativeFields,
//   //     },
//   //   })
//   // }
//   // else {
//   //   throw new Error('unsupported number or type of fields')
//   // }
//   return result
// }

interface Column {
  isNumber: boolean
  tableId: number
  text: string
  value: string
}

// export function getVisSpecFromGridItem(
//   gridItem: GridItemDataInterface
// ): VisSpec | null {
//   if (!gridItem.dataQuery || !Array.isArray(gridItem.columns)) {
//     return null
//   }

//   const fields: DataField[] = gridItem.columns.map((column: Column) => ({
//     id: column.value,
//     type: column.isNumber ? 'quantitative' : 'categorical',
//   }))

//   const widgetConfig = gridItem.dataQuery.data.widgetJson.config

//   const gridItemValueKeys: Set<string> = new Set(
//     widgetConfig.values.map((value: any) => value.col)
//   )
//   const gridItemLabelKeys: Set<string> = new Set(
//     widgetConfig.keys.map((key: any) => key.col)
//   )

//   return {
//     dataset: {
//       id: gridItem.dataQuery.data.id,
//       fields,
//     },
//     tableName: '',
//     chartType: (Array.isArray(gridItem.chartType)
//       ? gridItem.chartType[0]
//       : gridItem.chartType) as ChartDetailsEnum,
//     chartConfig: {
//       groups: [],
//       keys: fields.filter((field) => gridItemLabelKeys.has(field.id)),
//       values: fields.filter((field) => gridItemValueKeys.has(field.id)),
//     },
//   }
// }

// function getQuery(spec: VisSpec) {
//   const { keys: rows, values } = spec.chartConfig
//   return {
//     data: {
//       id: spec.dataset.id,
//       type: 'dataset',
//       widgetJson: {
//         config: {
//           keys: rows.map((row) => ({
//             col: row.id,
//             values: '',
//             filterType: '',
//           })),
//           values: values.map((value) => ({
//             col: value.id,
//             sort: '',
//             aggregate_type: 'sum', // TODO
//             topN: '',
//           })),
//           groups: undefined,
//           filters: [],
//           topN: 100,
//         },
//       },
//     },
//   }
// }

// const numberTypes = new Set([
//   'smallint',
//   'integer',
//   'bigint',
//   'numberic',
//   'real',
//   'double precision',
//   'serial',
//   'bigserial',
//   'decimal',
//   'int',
//   '',
//   'numeric',
// ])

// async function getGridItemFromVisSpec(
//   spec: VisSpec,
//   gridItem?: GridItemDataInterface
// ): Promise<GridItemDataInterface | null> {
//   let data: any[]
//   let dataId: number | null = null

//   if (!spec.dataTransform) {
//     const query = getQuery(spec)
//     const response = await getWidgetData(query)
//     if (response.data.code !== 100) {
//       return null
//     }

//     const {
//       data: responseData,
//       columns: responseColumns,
//     } = response.data.result
//     data = responseData.map((dataItem: any) => {
//       const setItem: any = {}
//       responseColumns.forEach((column: any, index: number) => {
//         setItem[column.name] = dataItem[index]
//       })
//       return setItem
//     })
//   } else {
//     const parameters = {
//       data: {
//         data: {
//           datasetId: spec.dataset.id,
//           ...spec.dataTransform,
//         },
//       },
//     }
//     const response = await preCalculate(parameters)
//     if (response.data.code !== 100) {
//       return null
//     }
//     const {
//       data: { result },
//     } = response

//     if (!result) {
//       return null
//     }

//     const outputTableName = result.data.result.output_params[0].out_table_name
//     dataId = result.id

//     const dataResponse = await viewData({
//       data: {
//         tableNames: outputTableName,
//       },
//     })

//     if (dataResponse.data.code !== 100) {
//       return null
//     }
//     const { head } = dataResponse.data.result[0]
//     interface HeadEntry {
//       name: string
//       type: string
//     }
//     const numericHeadEntries: HeadEntry[] = head.filter(
//       (headEntry: HeadEntry) => numberTypes.has(headEntry.type)
//     )
//     data = dataResponse.data.result[0].data.map((dataItem: any) => {
//       const newDataItem = { ...dataItem }
//       numericHeadEntries.forEach((numericHeadEntry) => {
//         newDataItem[numericHeadEntry.name] = +newDataItem[numericHeadEntry.name]
//       })
//       return newDataItem
//     })
//   }

//   // temp: filter out data records with null values
//   data = data.filter((d) => Object.keys(d).every((key) => d[key] !== null))

//   const {
//     chartType,
//     chartConfig: { keys, values, groups },
//   } = spec
//   const rowNames = keys.map((row) => row.id)
//   const valueNames = values.map((value) => value.id)

//   const result: any = {
//     ...gridItem,
//     chartType: spec.chartType,
//     chartOptions: {
//       ...(gridItem ? gridItem.chartOptions : {}),
//       value: data,
//       labelKey: rowNames[0],
//       valueKey: valueNames[0],
//       // xAxisAttribute: rowNames[0],
//       // yAxisAttribute: valueNames[0],
//     },
//     // dataQuery: query,
//     formData: {
//       ...(gridItem ? gridItem.formData : {}),
//       dataId: dataId || spec.dataset.id,
//       dataType: dataId ? 'recommend' : 'dataset',
//       tableName: dataId ? `derived-from-${spec.tableName}` : spec.tableName,
//       groupBy: groups.length > 0 ? groups[0].id : '',
//       labelKey: keys.length > 0 ? keys[0].id : '',
//       valueKey: values.map((field) => ({
//         func: '',
//         sort: '',
//         value: field.id,
//       })),
//       topK: 100,
//       isAggr: false,
//     },
//   }

//   if (data.length > 1000) {
//     result.showChart = false
//     result.statusText = '数据量超限'
//   } else {
//     if (
//       values.length > 1 &&
//       [
//         ChartDetailsEnum.groupBarChart,
//         ChartDetailsEnum.areaChart,
//         ChartDetailsEnum.lineChart,
//         ChartDetailsEnum.stackBarChart,
//       ].includes(spec.chartType)
//     ) {
//       // result.chartOptions.yAxisAttribute = values.map((value) => value.id)
//     }
//     if (chartType === ChartDetailsEnum.heatmapMatrix) {
//       result.chartOptions.heatMapDataKey = result.chartOptions.valueKey
//       result.chartOptions.valueKey = keys[1].id
//       // result.chartOptions.yAxisAttribute = keys[1].id
//       result.chartOptions.axisCategoricalDataSelection = 'all'
//     }
//     if (
//       values.length > 1 &&
//       chartType === ChartDetailsEnum.parallelCoordinates
//     ) {
//       result.chartOptions.parallelAxisNames = values.map((value) => value.id)
//       result.chartOptions.parallelAxisKeys =
//         result.chartOptions.parallelAxisNames
//       // eslint-disable-next-line prefer-destructuring
//       result.chartOptions.parallelGroupKey = rowNames[0]
//       result.chartOptions.axises = values.map((item) => item.id)
//       // eslint-disable-next-line prefer-destructuring
//       // result.chartOptions.xAxisAttribute = rowNames[0]
//     }
//     result.showChart = true
//   }

//   return result
// }

// export default function recommendVisualization(
//   spec: VisSpec,
//   gridItem?: GridItemDataInterface
// ): Promise<GridItemDataInterface | null>[] {
//   if (!spec) {
//     return []
//   }
//   const usedFields = getUsedFields(spec)
//   const usedFieldIds = new Set(usedFields.map((usedField) => usedField.id))
//   const unusedFields = spec.dataset.fields.filter(
//     (field) => !usedFieldIds.has(field.id)
//   )

//   let recommendedSpecs: VisSpec[] = []
//   recommendedSpecs = recommendedSpecs.concat(
//     recommendVisByFields(spec, usedFields)
//   )
//   unusedFields.forEach((unusedField) => {
//     recommendedSpecs = recommendedSpecs.concat(
//       recommendVisByFields(spec, [...usedFields, unusedField])
//     )
//   })

//   // TODO: filter out the original spec, then
//   const gridItemPromises = recommendedSpecs.map((recommendedSpec) =>
//     getGridItemFromVisSpec(recommendedSpec, gridItem)
//   )
//   return gridItemPromises
// }

// const iColumnDescToTypeMap: {
//   [key: string]: 'quantitative' | 'categorical'
// } = {
//   decimal: 'quantitative',
//   int: 'quantitative',
//   varchar: 'categorical',
//   text: 'categorical',
//   date: 'categorical',
// }

// function iColumnToDataField(column: IColumn): DataField {
//   return {
//     id: column.name,
//     type: iColumnDescToTypeMap[column.desc!],
//     semantic: column.semantic,
//   }
// }

/**
 * 获取不经数据转换直接用于推荐图表的数据
 * @param tableName 表名
 * @param taskId pipeline节点id
 */
export async function getTableData(
  tableName: string,
  taskId: number,
  pageSize: number = 50
) {
  const regex1 = /^(?:dataset\.)?(.*)$/
  const regex2 = /^(pipeline\.(?:view|solid_\w+)_\d+_\d+_)\d+$/
  tableName = regex1.exec(tableName)?.[1] ?? ''
  tableName = regex2.exec(tableName)?.[1] ?? tableName

  const response = await apiGetTableData({
    data: {
      curPage: 1,
      name: '_record_id_',
      pageSize,
      filter: [],
      table: tableName,
      taskId,
    },
  })

  return response.data?.result
}

/**
 * 根据数据表和已选字段获取数据转换和可视化的推荐参数
 * @param usedFields 已选字段
 * @param allFields 数据表所有字段
 */
// function recommendDataAndChartParameters(
//   usedFields: IColumn[],
//   allFields: IColumn[],
//   isExtend: boolean = false
// ): RecommendParameters[] {
//   const clusterIdField = allFields.find((field) =>
//     ['cluster_id', 'label'].includes(field.id)
//   )
//   if (clusterIdField) {
//     clusterIdField.type = 'categorical'
//   }

//   if (usedFields.length === 0) {
//     usedFields = allFields
//   }
//   const usedFieldIds = new Set(usedFields.map((f) => f.id))
//   const categoricalFields = allFields.filter(
//     (f) => usedFieldIds.has(f.id) && f.type === 'categorical'
//   ) // 分类属性，如字符串
//   const quantitativeFields = allFields.filter(
//     (f) => usedFieldIds.has(f.id) && f.type === 'quantitative'
//   ) // 数值型字段
//   const categoricalCount = categoricalFields.length
//   const quantitativeCount = quantitativeFields.length

//   const result: RecommendParameters[] = []
//   if (categoricalCount === 1 && quantitativeCount === 0) {
//     result.push(
//       {
//         transformSetting: {
//           transformMethod: 'bin',
//           transformConfig: <BinConfig>{
//             binFields: categoricalFields,
//             binMethod: 'count',
//           },
//         },
//         chartSetting: {
//           chartType: ChartDetailsEnum.barChart,
//           chartConfig: {
//             groups: [],
//             keys: categoricalFields,
//             values: [{ id: 'count', type: 'quantitative' }],
//           },
//         },
//       },
//       {
//         transformSetting: {
//           transformMethod: 'bin',
//           transformConfig: <BinConfig>{
//             binFields: categoricalFields,
//             binMethod: 'count',
//           },
//         },
//         chartSetting: {
//           chartType: ChartDetailsEnum.pieChart,
//           chartConfig: {
//             groups: [],
//             keys: categoricalFields,
//             values: [{ id: 'count', type: 'quantitative' }],
//           },
//         },
//       }
//       // TODO for categorical && ordinal???: linechart
//       // TODO for time: bin by year, month, day (then histogram, piechart
//       // TODO for space: bin by province,city,district (then histogram, piechart
//     )
//   } else if (categoricalCount === 0 && quantitativeCount === 1) {
//     const binCounts = [5, 10, 15]
//     const binMethods = ['count' /* 'average' /* , 'variance' */]
//     binCounts.forEach((binCount) => {
//       binMethods.forEach((binMethod) => {
//         const targetField = quantitativeFields[0]
//         const newFieldName =
//           binMethod === 'count'
//             ? binMethod
//             : `${binMethodsMap[binMethod]}_${targetField.id}`
//         result.push({
//           transformSetting: {
//             transformMethod: 'bin',
//             transformConfig: <BinConfig>{
//               binFields: [{ ...quantitativeFields[0], binCount }],
//               binMethod,
//               targetField,
//             },
//           },
//           chartSetting: {
//             chartType: ChartDetailsEnum.barChart,
//             chartConfig: {
//               groups: [],
//               keys: quantitativeFields.map((field) => ({
//                 ...field,
//                 id: `${field.id}_after`,
//               })),
//               values: [{ id: newFieldName, type: 'quantitative' }],
//             },
//           },
//         })
//       })
//     })
//   } else if (categoricalCount === 2 && quantitativeCount === 0) {
//     // result.push({
//     //   transformSetting: {
//     //     transformMethod: 'bin',
//     //     transformConfig: <BinConfig>{
//     //       binFields: categoricalFields,
//     //       binMethod: 'count',
//     //     },
//     //   },
//     //   chartSetting: {
//     //     chartType: ChartDetailsEnum.stackBarChart, // TODO bug
//     //     chartConfig: {
//     //       groups: [],
//     //       keys: categoricalFields,
//     //       values: [{ id: 'count', type: 'quantitative' }],
//     //     },
//     //   },
//     // })
//     if (!isExtend) {
//       result.push(
//         // TODO 不要stackbar 不要heatmap
//         {
//           transformSetting: {
//             transformMethod: 'bin',
//             transformConfig: <BinConfig>{
//               binFields: categoricalFields,
//               binMethod: 'count',
//             },
//           },
//           chartSetting: {
//             chartType: ChartDetailsEnum.heatmapMatrix,
//             chartConfig: {
//               groups: [],
//               keys: categoricalFields,
//               values: [{ id: 'count', type: 'quantitative' }],
//             },
//           },
//         }
//         // TODO scatterplot with size encoding count
//         // TODO binned by various space and time granularity
//       )
//     }
//   } else if (categoricalCount === 0 && quantitativeCount === 2) {
//     result.push({
//       chartSetting: {
//         chartType: ChartDetailsEnum.scatterplot,
//         chartConfig: {
//           groups: [],
//           // rows: [], // TODO
//           // values: quantitativeFields,
//           keys: [quantitativeFields[0]],
//           values: [quantitativeFields[1]],
//           colorCount: 1,
//         },
//       },
//     })

//     if (!isExtend) {
//       const binCounts = [5, 10, 15]
//       // TODO sum variance
//       const binMethods = [/* 'count', */ 'average' /* , 'sum', 'variance' */]

//       // TODO scatterplot size encoding count, binned by 2 quant fields
//       // 现在的scatterplot不支持
//       // binCounts.forEach((binCount) => {
//       //   result.push({
//       //     transformSetting: {
//       //       transformMethod: 'bin',
//       //       transformConfig: <BinConfig>{
//       //         binFields: quantitativeFields.map((field) => ({
//       //           ...field,
//       //           binCount,
//       //         })),
//       //         binMethod: 'count',
//       //       },
//       //     },
//       //     chartSetting: {chartType: ChartDetailsEnum.scatterplot,
//       //     chartConfig: {
//       //       columns: [],
//       //       rows: quantitativeFields,
//       //       values: [{ id: 'count', type: 'quantitative' }],
//       //     },
//       //   }})
//       // })

//       binCounts.forEach((binCount) => {
//         binMethods.forEach((binMethod) => {
//           quantitativeFields.forEach((field, index) => {
//             const targetField = quantitativeFields[1 - index]
//             const newFieldName = `${binMethodsMap[binMethod]}_${targetField.id}`
//             result.push({
//               transformSetting: {
//                 transformMethod: 'bin',
//                 transformConfig: <BinConfig>{
//                   binFields: [{ ...field, binCount }],
//                   binMethod,
//                   targetField,
//                 },
//               },
//               chartSetting: {
//                 chartType: ChartDetailsEnum.barChart,
//                 chartConfig: {
//                   groups: [],
//                   keys: [{ ...field, id: `${field.id}_after` }],
//                   values: [{ id: newFieldName, type: 'quantitative' }],
//                 },
//               },
//             })
//           })
//         })
//       })
//     }
//   } else if (categoricalCount === 1 && quantitativeCount === 1) {
//     result.push({
//       chartSetting: {
//         chartType: ChartDetailsEnum.scatterplot,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: quantitativeFields,
//           colorCount: 1,
//         },
//       },
//     })

//     if (!isExtend) {
//       // const binCounts = [5, 10, 15]
//       // TODO sum variance
//       const binMethods = [/* 'count', */ 'average' /* , 'sum', 'variance' */]

//       // TODO scatterplot size encoding count, binned by 1 cate & 1 quant
//       // 现在的scatterplot不支持
//       // binCounts.forEach((binCount) => {
//       //   result.push({
//       //     transformSetting: {
//       //       transformMethod: 'bin',
//       //       transformConfig: <BinConfig>{
//       //         binFields: [
//       //           ...categoricalFields,
//       //           { ...quantitativeFields[0], binCount },
//       //         ],
//       //         binMethod: 'count',
//       //       },
//       //     },
//       //     chartSetting: {chartType: ChartDetailsEnum.scatterplot,
//       //     chartConfig: {
//       //       columns: [],
//       //       rows: categoricalFields.concat(quantitativeFields),
//       //       values: [{ id: 'count', type: 'quantitative' }],
//       //     },
//       //   }})
//       // })

//       binMethods.forEach((binMethod) => {
//         const newFieldName = `${binMethodsMap[binMethod]}_${quantitativeFields[0].id}`
//         result.push({
//           transformSetting: {
//             transformMethod: 'bin',
//             transformConfig: <BinConfig>{
//               binFields: categoricalFields,
//               binMethod,
//               targetField: quantitativeFields[0],
//             },
//           },
//           chartSetting: {
//             chartType: ChartDetailsEnum.barChart,
//             chartConfig: {
//               groups: [],
//               keys: categoricalFields,
//               values: [{ id: newFieldName, type: 'quantitative' }],
//             },
//           },
//         })
//       })
//     }
//   } else if (categoricalCount === 2 && quantitativeCount === 1) {
//     result.push({
//       chartSetting: {
//         chartType: ChartDetailsEnum.scatterplot,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: quantitativeFields,
//         },
//       },
//     })
//   } else if (categoricalCount === 1 && quantitativeCount === 2) {
//     result.push({
//       chartSetting: {
//         chartType: ChartDetailsEnum.scatterplot,
//         chartConfig: {
//           groups: [],
//           keys: categoricalFields,
//           values: quantitativeFields,
//         },
//       },
//     })
//   }
//   // TODO scatterplot: 2 quant on axis, 1 quant on color
//   // 现在的scatterplot不支持
//   // else if (categoricalCount === 0 && quantitativeCount === 3) {
//   //   result.push({
//   //     chartSetting: {chartType: ChartDetailsEnum.scatterplot,
//   //     chartConfig: {
//   //       columns: [],
//   //       rows: [],
//   //       values: quantitativeFields,
//   //     },
//   //   }})
//   // }
//   // else {
//   //   throw new Error('unsupported number or type of fields')
//   // }
//   else {
//     // 平行坐标
//     // result.push({
//     //   chartSetting: {
//     //     chartType: ChartDetailsEnum.parallelCoordinates,
//     //     chartConfig: {
//     //       groups: [],
//     //       // keys: allFields.filter(f => f.type === 'categorical').slice(0, 1),
//     //       // values: allFields.filter(f => usedFieldIds.has(f.id)),
//     //       keys: [],
//     //       values: quantitativeFields.concat(categoricalFields),
//     //       colorCount: 1
//     //     },
//     //   },
//     // })
//   }
//   return result
// }

// function getRecommendedPcaParameters(
//   allFields: DataField[],
//   datasetAlgName: string
// ): RecommendParameters[] {
//   const labelFieldId = datasetAlgName === 'KMEANS' ? 'cluster_id' : 'label'
//   const quantitativeFields = allFields.filter(field => field.id !== labelFieldId && field.type === 'quantitative')
//   if (quantitativeFields.length === 2) {
//     return [{
//       chartSetting: {
//         chartType: ChartDetailsEnum.scatterplot,
//         chartConfig: {
//           groups: [],
//           keys: [{ id: labelFieldId, type: 'categorical' }],
//           values: quantitativeFields,
//           isoColor: datasetAlgName !== 'KMEANS'
//         },
//       }
//     }]
//   }
//   return [{
//     transformSetting: {
//       transformMethod: 'pca',
//       transformConfig: {
//         fields: quantitativeFields,
//         dimension: 2,
//         label: labelFieldId
//       }
//     },
//     chartSetting: {
//       chartType: ChartDetailsEnum.scatterplot,
//       chartConfig: {
//         groups: [],
//         keys: [{ id: labelFieldId, type: 'categorical' }],
//         values: [
//           { id: 'f1', type: 'quantitative' },
//           { id: 'f2', type: 'quantitative' }
//         ],
//         usePcaAxisTitle: true,
//         isoColor: datasetAlgName !== 'KMEANS'
//       },
//     }
//   }]
// }

// const AlgRecommendMapping: KeyValueStore = {
//   DBSCAN: 'DBSCANRecommendParameters',
//   KMEANS: 'KMEANSRecommendParameters',
//   PCA_DENSE: 'PCADENSERecommendParameters',
//   TSNE: 'TSNERecommendParameters',
//   LLE: 'LLERecommendParameters',
//   FP_GROWTH: 'FPGROWTHRecommendParameters',
//   PREFIX_SPAN: 'PREFIXSPANRecommendParameters',
//   ISO_FOREST: 'ISOFORESTRecommendParameters',
//   STAT_ANOMALY: 'STATANOMALYRecommendParameters',
// }

/**
 * 新版本不再需要 by zhangfanfan 2021-08-09
 * 获取算子默认可视化推荐参数
 * @param usedFields 选中的字段
 * @param allFields 全部字段
 * @param datasetAlgName 算子名称
 */
// function getAlgRecommendParameters(
//   usedFields: DataField[],
//   allFields: DataField[],
//   datasetAlgName: string,
//   algData?: KeyValueStore
// ): RecommendParameters[] {
//   if (usedFields.length === 0) {
//     usedFields = allFields
//   }
//   return (algorithmRecommend as KeyValueStore)[
//     AlgRecommendMapping[datasetAlgName]
//   ](usedFields, algData)
// }

/**
 * 获取地理语义的可视化推荐参数
 * @param usedFields 选中的字段
 * @param allFields 全部字段
 * @param targetCount 目标要匹配的规则列数 目前范围是1-3
 */
// function getGeoRecommendParameters(
//   usedFields: IColumn[],
//   allFields: IColumn[],
//   targetCount: number,
// ): RecommendParameters[] {
//   if (usedFields.length === 0) {
//     usedFields = allFields
//   }
//   const geoArray = usedFields.filter((item) =>
//     ['coordinate', 'ip', 'country', 'province', 'city'].includes(
//       item.semantic || ''
//     )
//   ) // 经纬度
//   const countryArray = usedFields.filter(
//     (item) => (item.semantic || '') === 'country'
//   ) // 国家名字段
//   const latArray = usedFields.filter((item) =>
//     ['latitude'].includes(item.semantic || '')
//   ) // 单独纬度字段
//   const lngArray = usedFields.filter((item) =>
//     ['longitude'].includes(item.semantic || '')
//   ) // 单独经度字段
//   const nonGeoArray = usedFields.filter(
//     (item) =>
//       ![
//         'coordinate',
//         'ip',
//         'country',
//         'province',
//         'city',
//         'latitude',
//         'longitude',
//       ].includes(item.semantic || '')
//   ) // 非地理语义字段
//   const numberArray = nonGeoArray.filter((item) =>
//     COLUMN_TYPE_NUMBER.has(item.desc ?? '')
//   ) // 数值字段
//   // const timeArray = nonGeoArray.filter(item => ['time'].includes(item.semantic || ''))

//   const numberCount = numberArray.length
//   const geoArrayCount = geoArray.length
//   const latArrayCount = latArray.length
//   const lngArrayCount = lngArray.length

//   if (
//     latArrayCount !== lngArrayCount ||
//     (latArrayCount === 0 && geoArrayCount === 0)
//   ) {
//     // 无有效的坐标点
//     return []
//   }
//   const result: RecommendParameters[] = []
//   const geoCount = latArrayCount + geoArrayCount
//   const transformFields = geoArray.filter(
//     (item) => item.semantic !== 'coordinate'
//   )
//   const needTransform = transformFields.length > 0 // 存在非坐标系的地理语义则需要转换，如省份、城市、ip等
//   let transformConfig = {}
//   if (needTransform) {
//     transformConfig = {
//       transformSetting: {
//         transformMethod: 'geoTransform',
//         transformConfig: {
//           fields: transformFields,
//         },
//       },
//     }
//   }
//   const geoCombineField: string[][] = []
//   if (latArrayCount > 0) {
//     // 存在单独的纬度字段，则需和单独经度字段一一匹配成组
//     latArray.forEach((item, index) => {
//       geoCombineField.push([
//         lngArray[index].name,
//         item.name,
//         `$$${lngArray[index].name}-${item.name}-${index}$$`,
//       ])
//     })
//   }

//   // 匹配列数为1的规则
//   if (targetCount === 1 && geoArray.length >= 1) {
//     geoArray.forEach((field: IColumn) => {
//       const transformSetting:any = [{
//         transformMethod: 'precalculate',
//         transformConfig: {
//           fields: [field],
//           method: 'count'
//         },
//       }]
//       result.push({ // point glyph
//         transformSetting,
//         chartSetting: {
//           chartType: ChartDetailsEnum.geographicMap,
//           chartConfig: {
//             groups: [],
//             glyphConfig: {
//               geoLayer: ['point'],
//             },
//             keys: geoArray,
//             values: [],
//           },
//         }
//       })
//       if (field.semantic !== '') {
//         transformSetting.push({
//           transformMethod: 'geoTransform',
//           transformConfig: {
//             fields: transformFields,
//           },
//         })

//         result.push({ // polygon glyph
//           transformSetting,
//           chartSetting: {
//             chartType: ChartDetailsEnum.geographicMap,
//             chartConfig: {
//               groups: [],
//               glyphConfig: {
//                 geoLayer: ['polygon'],
//               },
//               keys: geoArray,
//               values: [],
//             },
//           }
//         })
//       }
//     })
//     return result
//   }

//   // 根据地图语义列的个数和其他类型语义的个数进行不同推荐
//   if (geoCount === 1 && numberCount === 0) {
//     // 只选择了1个地图语义
//     result.push(
//       {
//         ...transformConfig,
//         chartSetting: {
//           chartType: ChartDetailsEnum.geographicMap,
//           chartConfig: {
//             groups: [],
//             glyphConfig: {
//               geoLayer: ['point'],
//               geoCombineField, // [[经度id，纬度id，合成的经纬度id]]单独的经度和维度字段，经度在前
//             },
//             keys: geoArray,
//             values: [],
//           },
//         },
//       },
//       {
//         ...transformConfig,
//         chartSetting: {
//           chartType: ChartDetailsEnum.geographicMap,
//           chartConfig: {
//             groups: [],
//             glyphConfig: {
//               geoLayer: ['heatmap'],
//               geoCombineField, // [[经度id，纬度id，合成的经纬度id]]单独的经度和维度字段，经度在前
//             },
//             keys: geoArray,
//             values: [],
//           },
//         },
//       }
//     )
//   } else if (geoCount === 1 && numberCount === 1) {
//     // 1个地图语义 + 1个数值
//     const commonConfig = {
//       groups: [],
//       keys: geoArray,
//       values: numberArray,
//     }
//     result.push(
//       {
//         ...transformConfig,
//         chartSetting: {
//           chartType: ChartDetailsEnum.geographicMap,
//           chartConfig: {
//             glyphConfig: {
//               geoLayer: ['point'],
//               geoCombineField, // [[经度id，纬度id，合成的经纬度id]]单独的经度和维度字段，经度在前
//             },
//             ...commonConfig,
//           },
//         },
//       }
//       // {
//       //   ...transformConfig,
//       //   chartSetting: {
//       //     chartType: ChartDetailsEnum.geographicMap,
//       //     chartConfig: {
//       //       geoLayer: ['point', 'text'],
//       //       ...commonConfig,
//       //     }
//       //   }
//       // },
//       // {
//       //   ...transformConfig,
//       //   chartSetting: {
//       //     chartType: ChartDetailsEnum.geographicMap,
//       //     chartConfig: {
//       //       geoLayer: ['contour'],
//       //       ...commonConfig
//       //     }
//       //   }
//       // }
//     )
//     if (countryArray.length > 0) {
//       // 国家 + 数值 => 国家区域分块图
//       result.push({
//         ...transformConfig,
//         chartSetting: {
//           chartType: ChartDetailsEnum.geographicMap,
//           chartConfig: {
//             glyphConfig: {
//               geoLayer: ['world'],
//               geoCombineField, // [[经度id，纬度id，合成的经纬度id]]单独的经度和维度字段，经度在前
//               encodingType: 'color',
//               subChartTrigger: 'tooltip',
//               subChartSize: [250, 80],
//               reverseMappingType: 'unk',
//               valueSeparator:
//                 '[1000,10000,50000,100000,500000,1000000,2000000,5000000]', // 针对疫情数据地图的临时数据分隔
//               selectColor: '#ffff00',
//             },
//             ...commonConfig,
//           },
//         },
//       })
//     }
//   } else if (geoCount >= 2 && numberCount >= 0) {
//     // 2个以上地图语义 + 数值（有数值则有编码，无数值则无编码）line 或者 多边形
//     const commonConfig = {
//       groups: [],
//       keys: geoArray,
//       values: numberArray,
//     }
//     result.push({
//       ...transformConfig,
//       chartSetting: {
//         chartType: ChartDetailsEnum.geographicMap,
//         chartConfig: {
//           glyphConfig: {
//             geoLayer: ['polygon'], // 多边形两个点的时候可画line
//             geoCombineField, // [[经度id，纬度id，合成的经纬度id]]单独的经度和维度字段，经度在前
//           },
//           ...commonConfig,
//         },
//       },
//     })
//   }
//   console.log('getGeoRecommendParameters', result)
//   return result
// }

/**
 * 根据字段语义进行可视化推荐
 * @param usedFields 已选字段
 * @param allFields 数据表所有字段
 */
// function getRecommendParametersBySemantic(
//   usedFields: IColumn[],
//   allFields: IColumn[]
// ): RecommendParameters[] | [] {
//   const result: RecommendParameters[] = [
//     ...getGeoRecommendParameters(usedFields, allFields, 1),
//   ]
//   return result
// }

/**
 * 根据数据表和已选字段类型获取数据转换和可视化的推荐参数
 * @param usedFields 已选字段
 * @param allFields 数据表所有字段
 */
export function getRecommendParameters(
  usedFields: IColumn[],
  allFields: IColumn[]
  // datasetAlgName?: string,
  // algData?: KeyValueStore
): RecommendParameters[] {
  // const usedFields2 = usedFields
  // .map((f) => iColumnToDataField(f))
  // .filter((f) => !!f.type)
  // const allFields2 = allFields
  // .map((f) => iColumnToDataField(f))
  // .filter((f) => !!f.type)

  // if (usedFields.length === 0 && datasetAlgName && ['KMEANS', 'ISO_FOREST'].includes(datasetAlgName)) {
  //   return getRecommendedPcaParameters(allFields2, datasetAlgName)
  // }
  let usedFieldsCount = usedFields.length
  let parameters: RecommendParameters[] = []
  while (parameters.length === 0 && usedFieldsCount > 0) {
    // 在没有匹配的情况下，筛选的列中取子集列，看看是否匹配
    console.log('usedFieldsCount', usedFieldsCount)
    parameters = [
      ...getRecommendParametersBySemantic(
        usedFields,
        allFields,
        usedFieldsCount
      ),
      ...getRecommendParametersByType(usedFields, allFields, usedFieldsCount),
    ]
    usedFieldsCount -= 1
  }

  // 算子的特定可视化推荐 去除
  // if (
  //   (usedFields2.length > 1 ||
  //     (usedFields2.length === 0 && allFields2.length > 1)) &&
  //   datasetAlgName &&
  //   AlgRecommendMapping[datasetAlgName]
  // ) {
  //
  //   return [
  //     ...semanticRecommendParameters,
  //     ...getAlgRecommendParameters(
  //       usedFields2,
  //       allFields2,
  //       datasetAlgName,
  //       algData
  //     ),
  //   ]
  // }

  // let recommended = recommendDataAndChartParameters(usedFields2, allFields2)
  // if (usedFields.length > 0 && usedFields.length < 3) {
  //   const usedFieldIds = new Set(usedFields2.map((f) => f.id))
  //   const unusedFields = allFields2.filter((f) => !usedFieldIds.has(f.id))
  //   recommended = recommended.concat(
  //     ...unusedFields.map((f) =>
  //       recommendDataAndChartParameters([...usedFields2, f], allFields2, true)
  //     )
  //   )
  // }

  console.log('parameters', parameters)
  return parameters
}

const recommenCache = {
  map: new Map(),
  get(parameters: RecommendParameters, tableName: string) {
    const key = JSON.stringify({
      transformSetting: parameters.transformSetting,
      tableName,
    })
    if (this.map.has(key)) {
      return this.map.get(key)
    }
    return null
  },
  set(parameters: RecommendParameters, tableName: string, value: any) {
    const key = JSON.stringify({
      transformSetting: parameters.transformSetting,
      tableName,
    })
    this.map.set(key, value)
  },
}

async function getPreCalculateData(
  parameters: RecommendParameters,
  tableName: string,
  cancelToken?: any
): Promise<{
  dataId: number
  tableName: string
  outputCols: string[] // 计算后表格的输出列
  binCalculate: boolean
} | null> {
  // by zhangfanfan 07-13 为HTTP更新数据临时去除缓存计算结果
  // const cache = recommenCache.get(parameters, tableName)
  // if (cache) {
  //   return cache
  // }

  try {
    const response = await preCalculate({
      data: {
        tableName,
        ...parameters.transformSetting?.filter(
          (item) => item.transformMethod === 'precalculate'
        )[0].transformConfig,
      },
      cancelToken,
    })
    const {
      tableNames,
      id,
      data: { outputCols, binCalculate },
    } = response.data?.result ?? {}
    const data = tableNames
      ? { dataId: id, tableName: tableNames, outputCols, binCalculate }
      : null
    if (data) {
      recommenCache.set(parameters, tableName, data)
    }
    return data
  } catch {
    return null
  }
}

// async function getPcaData(parameters: RecommendParameters, tableName: string) {
//   const cache = recommenCache.get(parameters, tableName)
//   if (cache) {
//     return cache
//   }

//   try {
//     const response = await calculatePca({
//       data: {
//         algName: 'pca',
//         label: parameters.transformSetting?.transformConfig.label,
//         source: tableName,
//         features: parameters.transformSetting?.transformConfig.fields
//           .map((f: any) => f.id)
//           .join(','),
//       },
//     })
//     const { id, tableName: resultTable } = response.data?.result ?? {}
//     const data = resultTable ? { dataId: id, tableName: resultTable } : null
//     if (data) {
//       recommenCache.set(parameters, tableName, data)
//     }
//     return data
//   } catch {
//     return null
//   }
// }

function getWidgetConfig(data: any, semantic: any) {
  data.chartOptions = {
    ...simpleCommonDefultOptions,
    // ...(defaultChartOptions[data.chartType] ?? {}),
    // ...data.formData,
    ...data.chartOptions,
  }

  // data.formData = {
  //   ...data.chartOptions,
  //   ...data.formData,
  // }

  if (
    typeof data.chartType === 'string' &&
    Array.isArray(chart2ArrayChartType[data.chartType])
  ) {
    data.chartType = chart2ArrayChartType[data.chartType]
  }
  data.widgetJson = getWidgetJson(data.chartOptions, data.chartType)

  const { keys, values, groups, filters } = data.widgetJson.config
  data.widgetJson.config = {
    ...data.widgetJson.config,
    keys: sortBy(keys, ['col']),
    values: sortBy(values, ['col']),
    groups: groups ? sortBy(groups, ['col']) : groups,
    filters: sortBy(filters, ['col']),
    semantic,
  }
  return data
}

/**
 * 解析geomap的渲染配置，主要是glyph
 * @param parameters 推荐参数
 * @returns geomap的渲染参数
 */
function parseGeoChartConfig(parameters: RecommendParameters) {
  const { chartConfig } = parameters.chartSetting
  // const { geoLayer } = chartConfig.glyphConfig
  const geoTransformSetting = parameters.transformSetting?.filter(
    (setting) => setting.transformMethod === 'geoTransform'
  )[0]
  const { transformMethod, transformConfig } = geoTransformSetting || {}
  const data: any = {
    ...chartConfig,
    // geoLayer,    // 临时注释掉，看在哪里用到的
    // glyph: geoLayer[0],
  }

  if (transformMethod === 'geoTransform') {
    data.geoTransform = {
      fields: (transformConfig?.fields as IColumn[]).map((item) => {
        return {
          semanticColumn: item.name,
          semantic: item.semantic,
        }
      }),
    }
  }
  return data
}

/**
 * 根据推荐参数获取可直接绘制的图表配置
 * @param parameters 推荐参数
 * @param tableName 表名
 * @param dataId pipeline节点id 或者 actionHistoryId
 */
export async function getRecommendedChart(
  parameters: RecommendParameters,
  tableName: string,
  dataId: number,
  dataType: string,
  taskId: number,
  cancelToken?: any
) {
  const {
    chartType,
    chartConfig: {
      keys,
      values,
      groups,
      // colorCount,
      // usePcaAxisTitle,
      // isoColor,
      colorField,
      seriesField,
      sizeField,
      pointRadius,
      heatMapDataKey,
    },
  } = parameters.chartSetting
  let rowNames = keys.map((row) => row.name)
  let valueNames = values.map((value) => value.name)

  const isTransformData = parameters.transformSetting
  const extraChartOptions: KeyValueStore = {} // 记录transform情况下需要额外展示的组件属性

  extraChartOptions.xAxisTitle = `${rowNames[0] || ''}`
  extraChartOptions.yAxisTitle = `${valueNames[0] || ''}`

  if (
    isTransformData &&
    isTransformData[0].transformMethod === 'precalculate'
  ) {
    const { transformMethod } = (parameters.transformSetting ?? [])[0] ?? {}
    let result
    if (transformMethod === 'precalculate') {
      // extraChartOptions.xAxisTitle = `${rowNames[0] || ''}`
      // extraChartOptions.xAxisTitle += transformConfig?.binFields[0].binCount
      //   ? ` (binCount:${transformConfig?.binFields[0].binCount})`
      //   : ''
      // if (
      //   transformConfig.fields.some(
      //     (field: { binCount?: number }) => field.binCount && field.binCount > 0
      //   )
      // ) {
      //   extraChartOptions.binCalculate = true // 经历了binCount的计算，后续value会需要额外处理
      // }
      result = await getPreCalculateData(parameters, tableName, cancelToken)
      //  根据后端返回的值设置，因为有可能配置里有binCount，但实际上并没有进行，可能数量过少
      extraChartOptions.binCalculate = result?.binCalculate ?? false
    }
    if (!result) {
      return null
    }
    ;({ dataId, tableName } = result)
    const { outputCols } = result
    if (outputCols.length > 0) {
      // 预计算生成新表和新列名，需要改变成新列名来取值
      if (chartType !== ChartDetailsEnum.geographicMap) {
        // eslint-disable-next-line @typescript-eslint/naming-convention
        rowNames = [outputCols[0]]
        valueNames = outputCols.slice(-1) //  约定取最后一位作为Y 轴【一般后端计算出的列都在最后一列】
        //  scatterplot heatmapMatrix较为特殊， 预计算后不是作为y 轴，作为sizeField;
        if (
          [
            ChartDetailsEnum.scatterplot,
            ChartDetailsEnum.heatmapMatrix,
          ].includes(chartType)
        ) {
          valueNames = outputCols.slice(1)
        }
        extraChartOptions.xAxisTitle = `${rowNames[0] || ''}`
        extraChartOptions.yAxisTitle = `${valueNames[0] || ''}`
      } else {
        // geomap 的字段获取逻辑特殊，需要单独处理
        extraChartOptions.outputCols = outputCols
      }
    }
    dataType = 'recommend'
  }

  const result: {
    chartType: ChartDetailsEnum
    chartOptions: any
    showChart: boolean
    statusText?: string
    tempId: number
  } = {
    chartType,
    chartOptions: {
      value: [],
      labelKey: rowNames[0] || '',
      valueKey: valueNames[0] || '',
      dataId,
      tableName,
      taskId,
      dataType,
      groupBy: groups.length > 0 ? groups[0].name : '',
      topK: 50,
      isAggr: false,
      // colorField: colorField || '',  //  scatter
      seriesField: seriesField || '', //  stack, group, line
      // sizeField: sizeField || '',  //  scatter
      // pointRadius: pointRadius || '',  //  scatter
      // heatMapDataKey: heatMapDataKey || '',  //  heatmap
      // xAxisAttribute: rowNames[0] || '',
      // yAxisAttribute: valueNames[0] || '',
      ...extraChartOptions,
    },
    showChart: true,
    // formData: {
    //   dataId,
    //   tableName,
    //   taskId,
    //   dataType,
    //   groupBy: groups.length > 0 ? groups[0].name : '',
    //   labelKey: keys.length > 0 ? keys[0].name : '',
    //   valueKey: values.map((field) => ({
    //     func: '',
    //     sort: '',
    //     value: field.name,
    //   })),
    //   topK: 50,
    //   isAggr: false,
    //   ...extraChartOptions,
    // },
    tempId: Math.floor(Math.random() * 1000000000),
  }

  if (chartType === ChartDetailsEnum.scatterplot) {
    result.chartOptions.topK = 700
  }

  // if (usePcaAxisTitle) {
  //   result.chartOptions.xAxisTitle = 'feature1'
  //   result.chartOptions.xAxisTitleFontSize = 14
  //   result.chartOptions.yAxisTitle = 'feature2'
  //   result.chartOptions.yAxisTitleFontSize = 14
  // }

  if (
    keys.length > 0 &&
    keys.length + values.length > 2 &&
    chartType === ChartDetailsEnum.scatterplot
  ) {
    ;[result.chartOptions.valueKey] = valueNames
    // [result.chartOptions.yAxisAttribute ]= valueNames
    // result.chartOptions.xAxisAttribute = valueNames[1] ?? rowNames[0]
    result.chartOptions.labelKey = rowNames[1] ?? rowNames[0]
  }
  if (chartType === ChartDetailsEnum.heatmapMatrix) {
    // result.chartOptions.heatMapDataKey = result.chartOptions.valueKey
    // result.chartOptions.valueKey = keys[1].name
    // result.chartOptions.yAxisAttribute = keys[1].id
    // result.chartOptions.axisCategoricalDataSelection = 'all'
    // result.chartOptions.legendBasicColor = '#873bf4'
    result.chartOptions.heatMapDataKey = heatMapDataKey
  }
  if (chartType === ChartDetailsEnum.scatterplot) {
    result.chartOptions = {
      ...result.chartOptions,
      sizeField,
      pointRadius,
      colorField,
    }
  }
  //  如果存在colorField 赋值给chartOptions
  // if (colorField) {
  //   result.chartOptions.colorField = colorField
  // }
  // if (seriesField) {
  //   result.chartOptions.seriesField = seriesField
  // }
  // if (chartType === ChartDetailsEnum.parallelCoordinates) {
  //   result.chartOptions.axises = values.map((item) => item.name)
  //   if (colorField) {
  //     result.chartOptions.categoryCol = colorField
  //   }
  //   result.chartOptions.topK = 200
  // }
  // if (chartType === ChartDetailsEnum.scatterplot) {
  //   result.chartOptions.colors = [
  //     'rgba(127, 201, 127, 0.5)',
  //     'rgba(190, 174, 212, 0.5)',
  //     'rgba(253, 192, 134, 0.5)',
  //     'rgba(255, 255, 153, 0.5)',
  //     'rgba(56, 108, 176, 0.5)',
  //     'rgba(240, 2, 127, 0.5)',
  //     'rgba(191, 91, 23, 0.5)',
  //     'rgba(102, 102, 102, 0.5)'
  //   ]
  // }

  if (chartType === ChartDetailsEnum.geographicMap) {
    const { outputCols } = result.chartOptions
    delete result.chartOptions.outputCols
    result.chartOptions = {
      ...result.chartOptions,
      // 取0 - 倒数第二个，默认为geo、类别等用于计算的字段
      labelKey: outputCols.length > 0 ? outputCols.slice(0, -1) : rowNames,
      // 取最后一个，默认为基于geomap计算的值
      valueKey: outputCols.length > 0 ? outputCols.slice(-1) : valueNames,
      ...parseGeoChartConfig(parameters),
    }
    result.chartOptions.topK = 200
  }
  const semantic =
    (isTransformData &&
      isTransformData[0].transformConfig.fields[0].semantic) ??
    ''
  const config = getWidgetConfig(result, semantic)
  let data = (await getAndDealWidgetData(config)) ?? []
  //  单列 - 地理信息 bin 操作后 不需要拼接
  if (config.chartOptions.binCalculate && !ifMeetCityProvince(semantic)) {
    data = parseBinCalculateData(data, config.chartOptions.labelKey)
  }

  const { labelKey } = result.chartOptions
  //  对于binCount barchart，不需要移除，其余均需要
  if (
    !(
      config.chartType[0] === ChartDetailsEnum.barChart &&
      config.chartOptions.binCalculate
    )
  ) {
    // config.chartOptions.value = removeNullEntries(data)
    config.chartOptions.value = transferLabelKeyToString(
      removeNullEntries(data),
      labelKey
    )
  } else {
    // config.chartOptions.value = data
    config.chartOptions.value = transferLabelKeyToString(data, labelKey)
  }

  console.log(config)
  return config
}

export function ifMeetCityProvince(semantic: any) {
  return ['city', 'province'].includes(semantic)
}

/**
 * 判断是否将字段转换成经纬度
 * @param chartOptions
 * @returns
 */
export function enableConvertToCoor(chartOptions: KeyValueStore) {
  const { geoTransform, geoLayer = [] } = chartOptions
  const disableConvert = new Set(['world', 'country-province', 'country-city']) // 兼容老的收藏chart数据
  if (geoTransform && !disableConvert.has(geoLayer[0])) {
    return true
  }
  return false
}

export async function getAndDealWidgetData(widget: {
  // formData: KeyValueStore
  widgetJson: KeyValueStore
  chartType: string | string[]
  chartOptions: KeyValueStore
}) {
  const request: KeyValueStore = {
    id: widget.chartOptions.dataId,
    type: widget.chartOptions.dataType,
    widgetJson: widget.widgetJson,
    taskId: widget.chartOptions.taskId,
  }
  if (enableConvertToCoor(widget.chartOptions)) {
    // 需要映射地理数据（省份、城市、ip等映射成经纬度）
    request.convert = widget.chartOptions.geoTransform.fields
  }
  const response = await getWidgetData({
    data: request,
  })
  // if (testWidgetData) {
  //   const result = testWidgetData
  //   const chartType = Array.isArray(widget.chartType)
  //     ? widget.chartType[1]
  //     : widget.chartType
  //   // 地图组件数据需要额外处理
  //   return dealData(result, chartType, widget)
  // }
  if (response.data.code === 100 && response.data.result) {
    const { result } = response.data
    const chartType = Array.isArray(widget.chartType)
      ? widget.chartType[1]
      : widget.chartType
    // 地图组件数据需要额外处理
    return dealData(result, chartType, widget)
  }

  return []
}

/**
 * 处理binCount 计算后的value，需要合并成bin区间
 */
export function parseBinCalculateData(
  data: KeyValueStore[],
  binFieldName: string
) {
  const newData = []
  for (let i = 0; i < data.length - 1; i += 1) {
    newData.push({
      ...data[i],
      [binFieldName]: `${data[i][binFieldName]}-${data[i + 1][binFieldName]}`,
    })
  }
  console.log(newData)
  return newData
}

export function removeNullEntries(data: any[]) {
  if (Array.isArray(data)) {
    return data.filter((d: any) => Object.values(d).every((v) => v !== null))
  }
  return data
}

/**
 * 处理labelKey 为 字符串，待chart断修复该问题，可移除该功能
 */
export function transferLabelKeyToString(data: any[], labelKey: string) {
  if (Array.isArray(data)) {
    // eslint-disable-next-line no-restricted-syntax
    for (const j of data) {
      // eslint-disable-next-line guard-for-in
      for (const i in j) {
        if (i === labelKey) {
          j[i] = String(j[i])
        }
      }
    }
  }
  return data
}
